package vr;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Logger;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;

public class Startlist implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -4399565377433857651L;
	Vector<Integer> startlist = new Vector<>();
	int[] hours = { 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 12 };

	public void fetchSources() {
		for (int hour : hours) {
			for (int minute = 0; minute < 59; minute += 2) {
				Logger.getGlobal().info("Fetching startlist: " + hour + ":" + minute); 
				for (int page = 1; page < 3; page++) {
					try {
						fetchSource(hour, minute, page);
					} catch (IOException e) {
						Logger.getGlobal().info(
								"Failed to fetch source:" + "Hour:" + hour
										+ "Minute:" + minute + "Page:" + page
										+ System.lineSeparator()
										+ e.getStackTrace().toString());
					}
				}
			}
		}
	}

	private String getFileName(int hour, int minute, int page) {
		return String.format("startlist/hour%02d/start_%02d_%02d_pg%02d.vrxml",hour, hour,minute,page);
	}

	private void fetchSource(int hour, int minute, int page)
			throws MalformedURLException, UnsupportedEncodingException,
			ProtocolException, IOException {
		Reader in = getReader(String.format("%02d:%02d", hour, minute), page);

		InputStream is = new ReaderInputStream(in);
		File file=new File(getFileName(hour, minute, page));
		file.getParentFile().mkdirs();
		FileOutputStream f = new FileOutputStream(file);
		IOUtils.copy(is, f);
		f.close();
	}

	public void generate(Boolean fromWeb) throws UnsupportedEncodingException,
			IOException {

		for (int hour : hours) {
			for (int minute = 0; minute < 59; minute += 2) {
				int maxPage=11;
				Logger.getGlobal().info(String.format("Fetching startlist: %02d:%02d", hour, minute)); 

				for (int page = 1; page < maxPage; page++) {

					InputStream is;

					if (fromWeb
							|| !Files.exists(Paths.get(getFileName(hour,
									minute, page)))) {
						fetchSource(hour, minute, page);
					}

					File file = new File(getFileName(hour, minute, page));
					is = new FileInputStream(file);

					Document doc = Jsoup.parse(is, "UTF-8", "",
							Parser.xmlParser());
					if( !doc.select("div.paginationwrap > li").isEmpty())
					{
						maxPage = Integer.parseInt(doc.select("div.paginationwrap > li").last().text());
					}
					if (doc.select("tr[data-type]").isEmpty()) {
						break;
					}
					for (Element e : doc.select("tr[data-type]")) {
						startlist.add(Integer.parseInt(e.attr("data-type")));
					}
				}

			}
		}

	}

	public Vector<Integer> get() throws UnsupportedEncodingException,
			IOException {
		return startlist;
	}

	private Reader getReader(String time, int page)
			throws MalformedURLException, UnsupportedEncodingException,
			IOException, ProtocolException {
		URL url = new URL(
				"http://vatternrundan.se/wp-admin/admin-ajax.php?lang=sv");
		Map<String, Object> params = new LinkedHashMap<>();

		params.put("action", "getParticipantPagination");
		params.put("query[RaceId]", "119");
		params.put("query[FirstName]", "");
		params.put("query[LastName]", "");
		params.put("query[City]", "");
		params.put("query[Bib]", "");
		params.put("query[StartTime]", time);
		params.put("query[Company]", "");
		params.put("page", page);

		StringBuilder postData = new StringBuilder();
		for (Map.Entry<String, Object> param : params.entrySet()) {
			if (postData.length() != 0)
				postData.append('&');
			postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
			postData.append('=');
			postData.append(URLEncoder.encode(String.valueOf(param.getValue()),
					"UTF-8"));
		}
		byte[] postDataBytes = postData.toString().getBytes("UTF-8");

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded");
		conn.setRequestProperty("Content-Length",
				String.valueOf(postDataBytes.length));
		conn.setDoOutput(true);
		conn.getOutputStream().write(postDataBytes);

		return new BufferedReader(new InputStreamReader(conn.getInputStream(),
				"UTF-8"));
	}
}
